package org.xa3apm.vote.hibernate.bean;

import java.io.Serializable;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;

import org.xa3apm.vote.exception.AuthenticationException;
import org.xa3apm.vote.exception.RegisterException;
import org.xa3apm.vote.hibernate.entities.Account;
import org.xa3apm.vote.hibernate.entities.Person;

@Stateless
public class AccountBean implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 5979197007093278936L;

	@PersistenceContext(name = "vote")
	private EntityManager em;

	public Account find(Long id) {
		return em.find(Account.class, id);
	}

	private Account save(Account account) {
		em.persist(account);
		return account;
	}

	public void update(Account account) {
		em.merge(account);
	}

	public Account checkCredential(String userName, String passowrd)
			throws AuthenticationException {
		Account account = (Account) em.createNamedQuery("Account.geByUserName")
				.setParameter("userName", userName).getSingleResult();
		if (account != null) {
			String storedPassword = account.getPassword();
			if (passowrd.equals(storedPassword.trim())) {
				return account;
			} else {
				throw new AuthenticationException("Authentication failed.");
			}
		} else {
			throw new AuthenticationException("User " + userName
					+ " does not exists in the database");
		}

	}

	public Account findByName(String userName) {
		return (Account) em.createNativeQuery("Account.geByUserName")
				.setParameter("userName", userName).getSingleResult();
	}

	public String register(String id, String userName, String password)
			throws RegisterException {
		try {
			Person person = (Person) (em.createNamedQuery("Person.getById")
					.setParameter("id", Long.parseLong(id)).getSingleResult());
			if (person.getAccount() == null) {
				try {
					em.createNamedQuery("Account.geByUserName")
							.setParameter("userName", userName)
							.getSingleResult();
					return "UserNameAlreadyExists";
				} catch (NoResultException e) {
					Account account = new Account(person, userName, password);
					save(account);
					return "Registered";
				}
			} else {
				throw new RegisterException("User with id " + id
						+ " already registered.");
			}
		} catch (NoResultException e) {
			throw new RegisterException("such id: " + id
					+ " does not exists in the database");
		}
		/*
		 * if (person!=null) { Account account = null; try{ account = (Account)
		 * em.createNamedQuery("Account.geByUserName").setParameter("userName",
		 * userName).getSingleResult(); } catch (NoResultException e) { account
		 * = new Account(person, userName, password); save(account); } if
		 * (account!=null) { return account; } else { throw new
		 * RegisterException("Username " + userName +
		 * " already registered. Please use different user name"); } } else {
		 * throw new RegisterException("such id: " + id +
		 * " does not exists in the database"); }
		 */
	}
}
